package com.frontop.terminal.downloader;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import com.frontop.terminal.constant.CommonNumBerCodConst;
import com.frontop.terminal.constant.DownloadConst;
import com.frontop.terminal.entity.File;
import com.frontop.terminal.entity.PlayList;
import com.frontop.terminal.entity.Program;
import com.frontop.terminal.util.ReadDataUtil;
import com.frontop.terminal.util.WriteDataUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicLong;

/**
 * <p>
 * 下载中心
 * </P>
 *
 * @author :CCC
 * @since :2021-06-10 09:34:00
 **/
@Slf4j
public class DownloadCenter {
    /**
     * 获得一个新的线程池，只有单个线程，策略如下：
     * 1. 初始线程数为 1
     * 2. 最大线程数为 1
     * 3. 默认使用LinkedBlockingQueue，默认队列大小为1024
     * 4. 同时只允许一个线程工作，剩余放入队列等待，等待数超过1024报错
     */
    private final static ExecutorService EXECUTOR_SERVICE;


    static {
        //获取线程池同时只允许一个线程工作，剩余放入队列等待，等待数超过1024报错
        EXECUTOR_SERVICE = ThreadUtil.newSingleExecutor();
    }

    /**
     * 加入下载任务
     *
     * @param task 任务线程
     */
    public static void setExecutorService(Runnable task) {
        EXECUTOR_SERVICE.submit(task);
    }

    /**
     * 刷新下载文件状态
     */
    public static Long refreshFileStatus(Long fileId, int status, String localPath, Integer type) {
        AtomicLong id = new AtomicLong();
        //改变文件下载状态
        List<File> localFiles = ReadDataUtil.getFile();
        if (null != localFiles && !localFiles.isEmpty()) {
            for (File f : localFiles) {
                if (f.getId().equals(fileId)) {
                    f.setDownloadStatus(status);
                    f.setLocations(localPath);
                }
            }

            //更新本地文件记录
            WriteDataUtil.write(localFiles, ReadDataUtil.FILE_LIST_CODING);
        }


        //如果不是已下载完成状态结束流程
        if (!DownloadConst.ACCOMPLISH.equals(status)) {
            return null;
        }

        //如果是互动程序
        if (type.equals(CommonNumBerCodConst.FOUR)) {
            List<Program> programList = ReadDataUtil.getProgramList();
            if (null != programList && !programList.isEmpty()) {
                for (Program entity : programList) {
                    if (entity.getFileId().equals(fileId)) {

                        //压缩包ZIP那解压后赋值
                        String zipSuffix = "zip";
                        if (FileUtil.getSuffix(localPath).equalsIgnoreCase(zipSuffix)) {
                            log.info("检测到互动程序是压缩包格式,开始解压文件...");

                            //解压文件
                            java.io.File zipFile;
                            try {
                                zipFile = ZipUtil.unzip(localPath, CharsetUtil.CHARSET_GBK);
                            } catch (Exception e) {
                                log.error("解压文件失败");
                                return null;
                            }
                            String exeSuffix = "exe";
                            //查找程序入口
                            String exePath = getExeFile(zipFile.listFiles(), exeSuffix);

                            if (!StrUtil.isEmpty(exePath)) {
                                entity.setLocation(exePath);
                            }

                        } else {
                            entity.setLocation(localPath);
                        }

                        id.set(Long.parseLong(entity.getId()));
                    }
                }

                WriteDataUtil.write(programList, ReadDataUtil.PROGRAM_LIST_CODING);
            }

        } else {
            //播放列表
            List<PlayList> playLists = ReadDataUtil.getPlayList();
            //如果是下载成功则同时更新播放列表local字段
            if (null != playLists && !playLists.isEmpty()) {
                //找出同一条文件id的播放列表
                for (PlayList p : playLists) {
                    Long playFileId = p.getFileId();
                    if (Objects.nonNull(playFileId) && playFileId.equals(fileId)) {
                        p.setLocation(localPath);
                        id.set(p.getId());
                    }
                }

                //更新本地播放列表
                WriteDataUtil.write(playLists, ReadDataUtil.PLAYLIST_LIST_CODING);
            }
        }


        return id.get();
    }

    /**
     * 查找程序入口
     *
     * @param fileArray 文件列表
     * @param exeSuffix 查找的文件后缀
     * @return 查找到返回要查找的文件路径
     */
    public static String getExeFile(java.io.File[] fileArray, String exeSuffix) {

        if (null != fileArray && fileArray.length > 0) {

            //查找程序入口
            for (java.io.File file : fileArray) {

                if (FileUtil.getSuffix(file.getName()).equalsIgnoreCase(exeSuffix)) {
                    log.info("找到程序入口：" + file.getPath());
                    return file.getPath();
                }
            }

            //当前文件找不到那进入文件夹查找
            for (java.io.File file : fileArray) {
                //如果是文件夹
                if (file.isDirectory()) {
                    log.info("进入[{}]目录查找", file.getPath());

                    java.io.File[] files = file.listFiles();
                    String exePath = getExeFile(files, exeSuffix);
                    if (null != exePath) {
                        return exePath;
                    }
                }
            }

            log.warn("未找到程序入口");
        }

        return null;
    }

    public static void main(String[] args) {
        java.io.File unzip = ZipUtil.unzip("D:\\工具\\xshell6\\SD.zip", CharsetUtil.CHARSET_GBK);

        java.io.File[] files = unzip.listFiles();
        for (java.io.File file : files) {
            if (FileUtil.getSuffix(file.getName()).equalsIgnoreCase("exe")) {
                System.out.println("找到程序入口：" + file.getPath());
            }
        }

    }
}
